package com.kebabeaters.nakebab.server.handler;

import java.util.ArrayList;
import java.util.List;

import com.gwtplatform.dispatch.server.ExecutionContext;
import com.gwtplatform.dispatch.server.actionhandler.ActionHandler;
import com.gwtplatform.dispatch.shared.ActionException;
import com.kebabeaters.nakebab.shared.action.tasterranking.GetTasterRankingAction;
import com.kebabeaters.nakebab.shared.action.tasterranking.GetTasterRankingAction.Result;
import com.kebabeaters.nakebab.shared.action.tasterranking.TasterRankingEntry;
import com.kebabeaters.nakebab.shared.dto.samples.HackfestSampleDataHolder;
import com.kebabeaters.nakebab.shared.dto.structures.Kebab;
import com.kebabeaters.nakebab.shared.dto.structures.Mark;
import com.kebabeaters.nakebab.shared.dto.structures.Restaurant;

public class GetTasterRankingHandler implements
		ActionHandler<GetTasterRankingAction, GetTasterRankingAction.Result> {

	@Override
	public Result execute(GetTasterRankingAction arg0, ExecutionContext arg1)
			throws ActionException {
		List<TasterRankingEntry> entries = new ArrayList<TasterRankingEntry>();

		TasterRankingEntry entry;

		new HackfestSampleDataHolder();

		for (Restaurant restaurant : HackfestSampleDataHolder.restaurants
				.values()) {
			entry = generateTasterRankingEntry(restaurant);
			entries.add(entry);
		}

		Result result = new Result();
		result.setEntries(entries);

		return result;
	}

	@Override
	public Class<GetTasterRankingAction> getActionType() {
		return GetTasterRankingAction.class;
	}

	@Override
	public void undo(GetTasterRankingAction arg0, Result arg1,
			ExecutionContext arg2) throws ActionException {
		// TODO Auto-generated method stub

	}

	private TasterRankingEntry generateTasterRankingEntry(Restaurant restaurant) {
		TasterRankingEntry result = new TasterRankingEntry();

		result.setRestaurant(restaurant);

		List<Mark> bestMarks = new ArrayList<Mark>();

		for (Kebab kebab : restaurant.getKebabs()) {
			for (Mark mark : kebab.getMarks()) {
				tryToReplace(mark, bestMarks);
			}
		}

		result.setBestTastersMarks(bestMarks);
		
		return result;
	}

	// TODO porownywac oceny wedlug plusow a nie gwiazdek!
	private boolean tryToReplace(Mark mark, List<Mark> currentBest) {
		boolean result = false;
		boolean delete = true;
		Integer replacementIndex = null;

		if (currentBest.size() < 3) {
			result = true;
			delete = false;
			
			for (int i = 0; i < currentBest.size(); i++)				
			{
				if (mark.getTaster().equals(currentBest.get(i).getTaster()))
				{
					if (mark.getEvaluation() > currentBest.get(i).getEvaluation())
					{
						delete = true;
						replacementIndex = i;						
					}
					else
					{
						result = false;
					}
					break;
				}
			}
			
		} else {
			for (int i = 0; i < currentBest.size(); i++) {
				if (mark.getEvaluation() > currentBest.get(i).getEvaluation()) {
					result = true;
					replacementIndex = i;

					for (int j = 0; j < currentBest.size(); j++) {
						if (i == j) {
							continue;
						}

						if (!mark.getTaster().equals(
								currentBest.get(j).getTaster())) {
							continue;
						} else {
							if (mark.getEvaluation() > currentBest.get(j)
									.getEvaluation()) {
								replacementIndex = j;
								break;
							} else {
								replacementIndex = -1;
								result = false;
								break;
							}
						}
					}
					if (replacementIndex != -1) {
						break;
					}
				}
			}
		}

		if (result) {
			if (delete) {
				currentBest.remove(replacementIndex);
				currentBest.add(replacementIndex, mark);
			} else {
				currentBest.add(mark);
			}

		}

		return result;
	}
}
